<?php 
namespace PsiFramework\Classes\Util\Parameters\DAO;

import("Classes.Util.Parameters.DAO.PluginDAO");

use \PsiFramework\Classes\Util\Parameters\DAO\PluginDAO;

/**
 * PsiFramework
 * Php Simple Framework
 *
 * @author Rémi San
 * @version beta
 */

/**
 * The PluginsDAO class is the generic class to retrieve all the plugins
 *
 * @package Util.Parameters.DAO
 */
class PluginsDAO
{

    protected static $_singleton = null;

    protected /*Plugin[]*/ $_plugins ;

    public function __construct()
    {
        $this->_plugins = array();
        $this->retrievePlugins();
    }

    public function getPlugins()
    {
        return $this->_plugins ;
    }

    protected function retrievePlugins()
    {
        $pluginsDirPath = getPluginsDirectory();
        $pluginsDir = opendir($pluginsDirPath);
        while ($entry = readdir($pluginsDir)) {
            if (!startsWith($entry, '.')) {
                $this->retrievePlugin($entry);
            }
        }
    }

    protected function getPlugin($pluginName)
    {
        $p = null ;
        if (!isset($this->_plugins[$pluginName])) {
            $this->retrievePlugin($pluginName);
        }
        if (isset($this->_plugins[$pluginName])) {
            $p = $this->_plugins[$pluginName] ;
        }
        return $p ;
    }

    protected function retrievePlugin($pluginName)
    {
        if (!isset($this->_plugins[$pluginName])) {
            $pluginConfig = getPluginConfigDirectory($pluginName);
            if (is_dir($pluginConfig)) {
                $configFile = $pluginConfig . '/plugin.config.xml' ;
                if (is_file($configFile)) {
                    $pluginDao = new PluginDAO();
                    $pluginDao->initByFile($configFile);
                    $plugin = $pluginDao->retrievePlugin();

                    if (!is_null($plugin)) {

                        $parent = null ;
                        $parentName = $pluginDao->getParentName();
                        if (!is_null($parentName)) {
                            $parent = $this->getPlugin($parentName);
                            if (is_null($parent)) {
                                throw new \Exception(
                                    'The parent Plugin "' . $parentName .
                                    '" for Plugin "' . $plugin->getName() .
                                    '" was not found.'
                                );
                            }
                        }
                        $plugin->setParent($parent);

                        $dependencies = array();
                        foreach (
                            $pluginDao->getDependeciesNames() as $dependecyName
                        ) {
                            $p = $this->getPlugin($dependecyName);
                            if (is_null($dependecyName)) {
                                throw new \Exception(
                                    'The dependency Plugin "' . $dependecyName .
                                    '" for Plugin "' . $plugin->getName() .
                                    '" was not found.'
                                );
                            } else {
                                $dependencies[] = $p ;
                            }
                        }
                        $plugin->setDependencies($dependencies);

                        $this->_plugins[$plugin->getName()] = $plugin ;
                    }
                }
            }
        }
    }

    /**
     * Function to be called instead of the constructor.
     *
     * @return     PluginsDAO instance
     */
    public static function getInstance()
    {

        if (self::$_singleton==null) {
            self::$_singleton = new PluginsDAO();
        }

        return self::$_singleton;
    }
}
